import React, { PureComponent } from 'react';
import { parse as cookieParse } from 'cookie';
import styles from './application.module.css';
import { STORAGEMAPPING } from '@/constants';
import { setCooKie } from '@/utils/storage';
import ShowMore from '../../components/showmore';

class Application extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      tabName: 'LocalStorage',
      storage: [],
      expandIndex: [],
      curKey: '',
      canEdit: false,
      editKey: '',
      editValue: '',
    };
  }
  componentDidMount() {
    const { storageType } = this.props;
    this.setState({
      storage: this.getStorage(storageType),
    });
  }
  getStorage(tabName) {
    const lowerTabName = tabName.toLowerCase();
    let storage = {};
    if (lowerTabName === 'localstorage') {
      storage = window.localStorage;
    }
    if (lowerTabName === 'sessionstorage') {
      storage = window.sessionStorage;
    }
    if (lowerTabName === 'cookie') {
      storage = cookieParse(document.cookie);
    }
    return Object.keys(storage).map(skey => {
      const value = storage[skey];
      return {
        key: skey,
        value,
        show: value.length > 300 ? false : true,
      };
    });
  }
  onSelectTabHandler(tabName) {
    this.props.onSelectTab(tabName);
    this.setState({
      tabName,
      storage: this.getStorage(tabName),
      curKey: '',
    });
  }
  getSubSelected(curTabName) {
    const { storageType } = this.props;
    if (curTabName === storageType) {
      return styles.mdebugSubSelected;
    }
    return;
  }
  onChange(e) {
    this.props.onSetKeywords({
      application: e.currentTarget.value,
    });
  }
  deleteAll() {
    const { storageType } = this.props;
    const { storage } = this.state;
    const lowerTabName = storageType.toLowerCase();
    if (lowerTabName === 'localstorage') {
      if (!!window.localStorage) {
        try {
          window.localStorage.clear();
        } catch (e) {
          alert('window.localStorage.clear() fail!');
        }
      }
    }
    if (lowerTabName === 'sessionstorage') {
      if (!!window.sessionStorage) {
        try {
          window.sessionStorage.clear();
        } catch (e) {
          alert('window.sessionStorage.clear() fail!');
        }
      }
    }
    if (lowerTabName === 'cookie') {
      storage.forEach(item => {
        setCooKie(item.key, '', -1);
      });
    }
    this.setState({
      storage: [],
    });
  }
  delete(flag) {
    const { storageType } = this.props;
    const { curKey, storage } = this.state;
    const key = curKey ? curKey : storage[0].key;
    const index = storage.findIndex(item => item.key === key);
    const lowerTabName = storageType.toLowerCase();
    if (lowerTabName === 'localstorage') {
      if (!!window.localStorage) {
        try {
          window.localStorage.removeItem(key);
        } catch (e) {
          alert('window.localStorage.removeItem() fail!');
        }
      }
    }
    if (lowerTabName === 'sessionstorage') {
      if (!!window.sessionStorage) {
        try {
          window.sessionStorage.removeItem(key);
        } catch (e) {
          alert('window.sessionStorage.removeItem() fail!');
        }
      }
    }
    if (lowerTabName === 'cookie') {
      setCooKie(key, '', -1);
    }
    if (flag) return;
    storage.splice(index, 1);
    this.setState({
      storage: [...storage],
      curKey: '',
    });
  }
  cellClickHandler(e) {
    this.setState({
      curKey: e.currentTarget.id,
    });
  }
  edit() {
    const { canEdit, curKey, editKey, editValue, storage } = this.state;
    const index = storage.findIndex(item => item.key === curKey);
    if (!curKey) return;
    const key = editKey || storage[index].key;
    const value = editValue || storage[index].value;
    if (canEdit) {
      this.delete(true);
      this.setStorageItem(key, value);
      storage[index].key = key;
      storage[index].value = value;
      this.setState({
        curKey: '',
      });
    }
    this.setState({
      storage: [...storage],
      canEdit: !canEdit,
    });
  }
  setStorageItem(key, value) {
    const { storageType } = this.props;
    const lowerTabName = storageType.toLowerCase();
    if (lowerTabName === 'localstorage') {
      if (!!window.localStorage) {
        try {
          window.localStorage.setItem(key, value);
        } catch (e) {
          alert('window.localStorage.removeItem() fail!');
        }
      }
    }
    if (lowerTabName === 'sessionstorage') {
      if (!!window.sessionStorage) {
        try {
          window.sessionStorage.setItem(key, value);
        } catch (e) {
          alert('window.sessionStorage.removeItem() fail!');
        }
      }
    }
    if (lowerTabName === 'cookie') {
      setCooKie(key, value);
    }
  }
  setEditKey(e) {
    this.setState({
      editKey: e.currentTarget.value,
    });
  }
  setEditInput(e, key) {
    this.setState({
      [key]: e.currentTarget.value,
    });
  }

  render() {
    const { storage, curKey, canEdit } = this.state;
    const { keywords = {} } = this.props;
    const { application: applicationWords } = keywords;
    const hasStorage = storage.length > 0;
    return (
      <div
        className={styles.mdebugActionApplicationCon}
        style={{
          border: hasStorage ? undefined : 'none',
        }}>
        <div className={styles.mdebugFixedHeader}>
          <div className={styles.settings}>
            <input
              type="text"
              placeholder="filter application"
              onChange={this.onChange.bind(this)}
              className={styles.applicationinput}
              value={applicationWords}
            />
            <div className={styles.allDelete} onClick={() => this.deleteAll()}>
              <img
                src=""
                alt=""
                style={{ width: '14px' }}
              />
            </div>
            <div className={styles.delete} onClick={() => this.delete()}>
              <img
                src=""
                alt=""
                style={{ width: '11px' }}
              />
            </div>
            <div className={styles.mdebugEdit} onClick={() => this.edit()}>
              {canEdit ? (
                <img
                  src=""
                  alt=""
                  className={styles.editImg}
                />
              ) : (
                <img
                  src=""
                  className={styles.editImg}
                  alt=""
                />
              )}
            </div>
          </div>
          <ul className={styles.mdebugAction}>
            {STORAGEMAPPING.map(tabName => (
              <li
                className={this.getSubSelected(tabName)}
                onClick={() => this.onSelectTabHandler(tabName)}>
                {tabName}
              </li>
            ))}
          </ul>
        </div>
        <div>
          {hasStorage && (
            <ul className={styles.mdebugApplicationHeaderUl}>
              <li className={styles.mdebugApplicationHeaderKeyName}>Key</li>
              <li className={styles.mdebugApplicationHeaderValueName}>Value</li>
            </ul>
          )}
          <table
            className={hasStorage ? styles.mdebugApplication : styles.mdebugApplicationNone}
            style={{
              border: hasStorage ? undefined : 'none',
            }}>
            {storage
              .filter(cstorage => {
                const { key, value } = cstorage;
                return (
                  !applicationWords ||
                  key.toLowerCase().indexOf(applicationWords.toLowerCase()) !== -1 ||
                  value.toLowerCase().indexOf(applicationWords.toLowerCase()) !== -1
                );
              })
              .map(storageUnit => {
                const { key, value } = storageUnit;
                return (
                  <tr
                    key={storageUnit.key}
                    id={storageUnit.key}
                    className={`${styles.mdebugApplicationTr} ${curKey === storageUnit.key &&
                      styles.mdebugTrActive}`}
                    onClick={e => this.cellClickHandler(e)}>
                    <td
                      className={styles.mdebugApplicationKeyName}
                      style={{
                        boder: '1px solid  #eee',
                      }}>
                      {key === curKey && canEdit ? (
                        <input
                          type="text"
                          defaultValue={key}
                          className={styles.mdebugEditInput}
                          onChange={e => this.setEditInput(e, 'editKey')}
                        />
                      ) : (
                        <ShowMore key={key}>{key}</ShowMore>
                      )}
                    </td>
                    <td
                      className={styles.mdebugApplicationValueName}
                      style={{
                        boder: '1px solid  #eee',
                      }}>
                      {key === curKey && canEdit ? (
                        <input
                          type="text"
                          defaultValue={value}
                          className={styles.mdebugEditInput}
                          onChange={e => this.setEditInput(e, 'editValue')}
                        />
                      ) : (
                        <ShowMore>{value}</ShowMore>
                      )}
                    </td>
                  </tr>
                );
              })}
          </table>
        </div>
      </div>
    );
  }
}

export default Application;
